package com.amos.muexamclient.sys.service.impl;

import com.amos.exception.BizExceptionEnum;
import com.amos.muexamclient.sys.entity.SysRoleEntity;
import com.amos.muexamclient.sys.mapper.SysRoleMapper;
import com.amos.muexamclient.sys.service.SysRoleDeptService;
import com.amos.muexamclient.sys.service.SysRoleService;
import com.amos.muexamclient.sys.service.SysUserRoleService;
import com.amos.muexamclient.sys.service.dto.SysRoleDTO;
import com.amos.muexamclient.sys.service.dto.SysRoleDeptDTO;
import com.amos.muexamcore.core.AbstractPageService;
import com.amos.muexamcore.core.BaseMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * Copyright © 2018 五月工作室. All rights reserved.
 *
 * @Package com.amos.muexamclient.sys.service.impl
 * @ClassName SysRoleServiceImpl
 * @Description TODO
 * @Author Amos
 * @Modifier
 * @Date 2020-03-24 14:35:56
 * @Version 1.0
 **/
@Service
public class SysRoleServiceImpl extends AbstractPageService<SysRoleDTO, SysRoleEntity> implements SysRoleService {

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysRoleDeptService roleDeptService;

    @Autowired
    private SysUserRoleService userRoleService;

    /**
     * 条件查询
     *
     * @param dto 查询的条件
     */
    @Override
    public List<SysRoleDTO> list(SysRoleDTO dto) {
        return this.getMapper().select(dto);
    }

    /**
     * 返回BaseDao对象
     */
    @Override
    public BaseMapper<SysRoleEntity, SysRoleDTO> getMapper() {
        return sysRoleMapper;
    }

    /**
     * 保存之间的校验
     *
     * @param dto 保存的对象
     */
    @Override
    public void preValidate(SysRoleDTO dto) {
        this.validateRoleName(dto.getRoleName(), dto.getId());

        this.validateRoleKey(dto.getRoleKey(), dto.getId());
    }

    private void validateRoleKey(String roleKey, String id) {
        List<SysRoleDTO> list = this.sysRoleMapper.getRoleByKey(roleKey);
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        SysRoleDTO role = list.get(0);
        if (StringUtils.isEmpty(id)) {
            BizExceptionEnum.DEFINED_EXCEPTION.definedMsg("新增角色'" + role.getRoleName() + "'失败，角色权限已存在").throwException();
        } else {
            if (!role.getId().equalsIgnoreCase(role.getId())) {
                BizExceptionEnum.DEFINED_EXCEPTION.definedMsg("修改角色'" + role.getRoleName() + "'失败，角色权限已存在").throwException();
            }
        }
    }

    private void validateRoleName(String roleName, String id) {
        SysRoleDTO role = new SysRoleDTO();
        role.setRoleName(roleName);
        List<SysRoleDTO> list = this.list(role);
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        if (StringUtils.isEmpty(id)) {
            BizExceptionEnum.DEFINED_EXCEPTION.definedMsg("新增角色'" + role.getRoleName() + "'失败，角色名称已存在").throwException();
        } else {
            role = list.get(0);
            if (!role.getId().equalsIgnoreCase(role.getId())) {
                BizExceptionEnum.DEFINED_EXCEPTION.definedMsg("修改角色'" + role.getRoleName() + "'失败，角色名称已存在").throwException();
            }
        }
    }

    /**
     * 添加子集数据
     *
     * @param id  主表ID
     * @param dto 主表DTO对象
     */
    @Override
    public void appendSubsidiary(String id, SysRoleDTO dto) {

    }

    @Override
    public Set<String> selectRolePermissionByUserId(String id) {
        Set<SysRoleEntity> sets = sysRoleMapper.selectRolePermissionByUserId(id);
        if (CollectionUtils.isEmpty(sets)) {
            return Collections.emptySet();
        }
        Set<String> permsSet = new HashSet<>();
        sets.stream().filter(item -> StringUtils.isEmpty(item)).forEach(item -> {
            permsSet.addAll(Arrays.asList(item.getRoleKey().trim().split(",")));
        });
        return permsSet;
    }

    @Override
    public List<SysRoleDTO> selectRoleUserId(String id) {
        return this.sysRoleMapper.selectRoleByUserId(id);
    }

    @Override
    public void checkRoleAllowed(SysRoleDTO role) {
        if (role.isAdmin()) {
            BizExceptionEnum.DEFINED_EXCEPTION.definedMsg("不能更改管理员权限").throwException();
        }
    }

    @Override
    public int authDataScope(SysRoleDTO role) {
        this.save(role);
        roleDeptService.deleteRoleDeptByRoleId(role.getId());
        return this.insertRoleDept(role);
    }

    public int insertRoleDept(SysRoleDTO role) {
        int rows = 1;
        // 新增角色与部门（数据权限）管理
        List<SysRoleDeptDTO> list = new ArrayList<SysRoleDeptDTO>();
        for (String deptId : role.getDeptIds()) {
            SysRoleDeptDTO rd = new SysRoleDeptDTO();
            rd.setRoleId(role.getId());
            rd.setDeptId(deptId);
            rd.setCreateTime(new Date());
            rd.setModifyTime(new Date());
            rd.setId(com.amos.util.StringUtils.generateUuid());
            list.add(rd);
        }
        if (list.size() > 0) {
            rows = roleDeptService.batchRoleDept(list);
        }
        return rows;
    }

    @Override
    public int deleteRoleByIds(String[] roleIds) {
        for (String roleId : roleIds) {
            SysRoleDTO role = new SysRoleDTO();
            role.setId(roleId);
            checkRoleAllowed(role);
            role = this.load(roleId);
            if (countUserRoleByRoleId(roleId) > 0) {
                BizExceptionEnum.DEFINED_EXCEPTION.definedMsg(String.format("%1$s已分配,不能删除", role.getRoleName())).throwException();
            }
        }
        return this.sysRoleMapper.deleteRoleByids(roleIds);
    }

    private int countUserRoleByRoleId(String roleId) {
        return userRoleService.countUserRoleByRoleId(roleId);
    }

    @Override
    public List<SysRoleDTO> optionSelect() {
        return this.sysRoleMapper.optionSelect();
    }
}
